/*
 *  $TEAM_NAME Space Trader
 */
package models;



import java.awt.geom.Point2D;
import java.util.Random;

import javax.xml.bind.annotation.XmlElement;

/**
 * The solar system represents both the planet and the system. It is a place
 * that the player can travel to and buy and sell goods amont other things.
 * 
 * @author bradley
 * @version 1.0
 */
public class StarSystem {
	/**
	 * 0.01
	 */
	private static final double OONE = 0.01;
	
	/**
	 * 0.02
	 */
	private static final double OTWO = 0.02;
	
	/**
	 * field
	 */
	protected String name;
	
	/**
	 * field
	 */
	protected TechLevel techLevel;
	
	/**
	 * field
	 */
	protected ResourceCondition resourceCondition;
	
	/**
	 * field
	 */
	protected Point2D.Double location;
	
	/**
	 * field
	 */
	protected double radius;
	
	/**
	 * field
	 */
	protected boolean inRange;
	
	/**
	 * field
	 */
	protected Marketplace marketplace;
	
	/**
	 * field
	 */
	protected Shipyard shipyard;
	
	/**
	 * field
	 */
	protected Approach.ApproachType approachType;

	/**
	 * Creates a randomly generated solar system with the name inputed.
	 * 
	 * @param name
	 *            - name of the system
	 * @return - a randomly generated system.
	 */
	public static StarSystem randomStarSystemWithName(String name) {

		final StarSystem ss = new StarSystem();
		final Random rng = new Random();

		// Generate the location and size of the new system
		ss.location = new Point2D.Double(rng.nextDouble(), rng.nextDouble());
		ss.radius = rng.nextDouble() * OTWO + OONE;

		// Randomize the tech level of the system.
		final TechLevel[] levels = TechLevel.values();
		ss.techLevel = levels[rng.nextInt(levels.length)];

		// Randomize the default resource condition of the system.
		final ResourceCondition[] conditions = ResourceCondition.values();
		ss.resourceCondition = conditions[rng.nextInt(conditions.length)];

		//Randomize the approach type
		ss.approachType = Approach.ApproachType.values()[(int) (
				Math.random() * Approach.ApproachType.values().length)];
		
		// set name
		ss.name = name;

		// Marketplace
		ss.marketplace = new Marketplace(ss);
		
		// Shipyard
		ss.shipyard = new Shipyard(ss);

		return ss;
	}

	/**
	 * Set the location on the system map
	 * @param location
	 */
	public void setLocation(Point2D.Double location) {
		this.location = location;
	}

	/**
	 * Getter for the location
	 * 
	 * @return - gets the location
	 */
	@XmlElement
	public Point2D.Double getLocation() {
		return location;
	}

	/**
	 * Getter for the radius
	 * 
	 * @return - gets the radius
	 */
	public double getRadius() {
		return radius;
	}

	/**
	 * Set the name
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Set the tech level
	 * @param techLevel
	 */
	public void setTechLevel(TechLevel techLevel) {
		this.techLevel = techLevel;
	}

	/**
	 * set the resource condition
	 * @param resourceCondition
	 */
	public void setResourceCondition(ResourceCondition resourceCondition) {
		this.resourceCondition = resourceCondition;
	}

	/**
	 * Set the radius
	 * @param radius
	 */
	public void setRadius(double radius) {
		this.radius = radius;
	}

	/**
	 * Set the marketplace
	 * @param marketplace
	 */
	public void setMarketplace(Marketplace marketplace) {
		this.marketplace = marketplace;
	}

	/**
	 * Getter for the name
	 * 
	 * @return the name of the planet
	 */
	public String getName() {
		return name;
	}

	/**
	 * Getter for the tech level
	 * 
	 * @return - the tech level of the system
	 */
	public TechLevel getTechLevel() {
		return techLevel;
	}

	/**
	 * Getter for the resource condition
	 * 
	 * @return - gets the resource condition
	 */
	public ResourceCondition getResourceCondition() {
		return resourceCondition;
	}

	/**
	 * Gets the marketplace
	 * @return the marketplace
	 */
	public Marketplace getMarketplace() {
		return marketplace;
	}

	/**
	 * Gets the distance to the solar system from the current system
	 * 
	 * @param ss
	 *            - the other system
	 * @return - the distance as a double
	 */
	public double distanceTo(StarSystem ss) {
		return location.distance(ss.getLocation());
	}

	/**
	 * Gets if it is in range
	 * @return if its in range
	 */
	public boolean getInRange() {
		return this.inRange;
	}

	/**
	 * Sets if it is in range
	 * @param inRange
	 */
	public void setInRange(boolean inRange) {
		this.inRange = inRange;
	}

	/**
	 * To string method for the system
	 * 
	 * @return - string representation of system
	 */
	public String toString() {
		String str = "Star System:";

		str += "\n\tname:\t\t" + name;
		str += "\n\tlocation:\t" + location;
		str += "\n\tresource:\t" + resourceCondition;

		return str;
	}

	/**
	 * Get the shipyard
	 * @return the shipyard
	 */
	public Shipyard getShipyard() {
		return shipyard;
	}

	/**
	 * Sets the shipyard
	 * @param shipyard
	 */
	public void setShipyard(Shipyard shipyard) {
		this.shipyard = shipyard;
	}

	/**
	 * @return the approachType
	 */
	public Approach.ApproachType getApproachType() {
		return approachType;
	}

	/**
	 * @param approachType the approachType to set
	 */
	public void setApproachType(Approach.ApproachType approachType) {
		this.approachType = approachType;
	}
}
